home *** CD-ROM | disk | FTP | other *** search
- // BannerView.cpp : implementation of the CBannerView class
- //
-
- #include "stdafx.h"
- #include "Banner.h"
- #include "Metrics.h"
- #include "BannDoc.h"
- #include "BannView.h"
- #include "MainFrm.h"
-
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
-
-
-
- int CBannerView::s_nRulerTickSize = 10;
- int CBannerView::s_nRulerNumberSize = 20; // just used for the rect, not the numbers.
-
- /////////////////////////////////////////////////////////////////////////////
- // CBannerView
-
- IMPLEMENT_DYNCREATE(CBannerView, CScrollView)
-
- BEGIN_MESSAGE_MAP(CBannerView, CScrollView)
- //{{AFX_MSG_MAP(CBannerView)
- ON_COMMAND(ID_BANNER_TEXT, OnBannerText)
- ON_COMMAND(ID_PAGES, OnPageBreaks)
- ON_COMMAND(ID_RULER, OnRuler)
- ON_UPDATE_COMMAND_UI(ID_RULER, OnUpdateRuler)
- ON_UPDATE_COMMAND_UI(ID_PAGE_BREAKS, OnUpdatePageBreaks)
- ON_WM_CREATE()
- ON_COMMAND(ID_FILE_PRINT, OnFilePrint)
- ON_WM_ERASEBKGND()
- ON_WM_KEYDOWN()
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
-
- /////////////////////////////////////////////////////////////////////////////
- // CBannerView construction/destruction
-
- CBannerView::CBannerView()
- {
- m_bRuler = TRUE;
- m_bPageBreaks = TRUE;
- m_nCurrZoom = CBannerMetrics::DefaultZoom();
- m_fontScreen.m_hObject = NULL;
- m_fontPrinter.m_hObject = NULL;
- m_rcMarginsPrintDlg = CRect(1250,1000,1250,1000); // 1000ths of inches
- }
-
- CBannerView::~CBannerView()
- {
- if(m_fontScreen.m_hObject != NULL)
- m_fontScreen.DeleteObject();
- }
-
-
-
-
- /////////////////////////////////////////////////////////////////////////////
- // CBannerView diagnostics
-
- #ifdef _DEBUG
- void CBannerView::AssertValid() const
- {
- CScrollView::AssertValid();
- }
-
- void CBannerView::Dump(CDumpContext& dc) const
- {
- CScrollView::Dump(dc);
- }
-
- CBannerDoc* CBannerView::GetDocument() // non-debug version is inline
- {
- ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CBannerDoc)));
- return (CBannerDoc*)m_pDocument;
- }
- #endif //_DEBUG
-
- /////////////////////////////////////////////////////////////////////////////
- // CBannerView message handlers
-
- void CBannerView::ComputeSizes(CDC *pPrinterDC /* = NULL */)
- {
- CDC PrinterDC;
- CDC *pScreenDC = GetDC();
- BOOL bDeleteTempPrinterDC = FALSE;
-
- // Query the printer page size (use defaults if no printer is available)
- // Note: it is not possible to get the margins at this point... we have to use
- // the cached copy (m_rcMarginsPrintDlg).
- CPrintDialog printDlg(FALSE);
- printDlg.GetDefaults();
- if(printDlg.m_pd.hdc == NULL)
- {
- // No printer detected, so use default information built into CBannerMetrics
- pPrinterDC = pScreenDC;
- m_sizePagePrinter = CSize(0,0);
- }
- else
- {
- // Printer detected, update mxPrinter with the default information
- bDeleteTempPrinterDC = TRUE;
- pPrinterDC = &PrinterDC;
- pPrinterDC->Attach(printDlg.m_pd.hdc);
- m_sizePagePrinter = CSize(pPrinterDC->GetDeviceCaps(HORZRES),
- pPrinterDC->GetDeviceCaps(VERTRES));
- }
-
- // Get the printer metrics
- CBannerMetrics mxPrinter(pPrinterDC);
-
- // Come up with defaults for m_sizePagePrinter if we need to
- if((m_sizePagePrinter.cx == 0) || (m_sizePagePrinter.cy == 0))
- {
- m_sizePagePrinter.cx = 10500 * mxPrinter.Inch().cx / 1000;
- m_sizePagePrinter.cy = 8000 * mxPrinter.Inch().cy / 1000;
- }
-
- // Convert margins from 1000th" to pixels
- m_rcMarginsPrinter = ScaleSize(m_rcMarginsPrintDlg, mxPrinter.Inch(), CSize(1000,1000));
-
- // Get size of view for the printer (large!), add in margins, and round up page-wise
- m_sizeTextPrinter = GetTextSize(pPrinterDC);
- if((m_sizeTextPrinter.cx == 0) || (m_sizeTextPrinter.cy == 0))
- m_sizeViewPrinter = m_sizePagePrinter;
- else
- {
- m_sizeViewPrinter = m_sizeTextPrinter;
- m_sizeViewPrinter.cx += m_rcMarginsPrinter.left + m_rcMarginsPrinter.right;
- m_sizeViewPrinter.cy += m_rcMarginsPrinter.top + m_rcMarginsPrinter.bottom;
- m_sizeViewPrinter.cx += m_sizePagePrinter.cx - (m_sizeViewPrinter.cx % m_sizePagePrinter.cx);
- m_sizeViewPrinter.cy += m_sizePagePrinter.cy - (m_sizeViewPrinter.cy % m_sizePagePrinter.cy);
- }
-
- // Calculate page size count
- m_sizePageCount.cx = m_sizeViewPrinter.cx / m_sizePagePrinter.cx;
- m_sizePageCount.cy = m_sizeViewPrinter.cy / m_sizePagePrinter.cy;
-
- // Derive metrics for the screen
- CBannerMetrics mxScreen(pScreenDC, m_nCurrZoom);
- m_sizeTextScreen = GetTextSize(pScreenDC, m_nCurrZoom);
- m_sizePageScreen = ScaleSize(m_sizePagePrinter, mxScreen.Inch(), mxPrinter.Inch());
- m_sizeViewScreen = ScaleSize(m_sizeViewPrinter, mxScreen.Inch(), mxPrinter.Inch());
- m_rcMarginsScreen = ScaleSize(m_rcMarginsPrinter, mxScreen.Inch(), mxPrinter.Inch());
-
- // Delete the temporary printer DC from the print dialog
- if(bDeleteTempPrinterDC)
- pPrinterDC->DeleteDC();
- }
-
-
-
- void CBannerView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
- {
- CWaitCursor* pWait = new CWaitCursor;
-
- ComputeSizes();
-
- CRect rcWnd;
- GetClientRect(&rcWnd);
- CSize sizeScrollPage(m_sizeViewScreen.cx/m_sizePageCount.cx,
- m_sizeViewScreen.cy/m_sizePageCount.cy);
- CSize sizeScrollLine(rcWnd.Width()/10, rcWnd.Height()/6);
- SetScrollSizes(MM_TEXT,m_sizeViewScreen,sizeScrollPage,sizeScrollLine);
-
- if(m_fontScreen.m_hObject != NULL)
- m_fontScreen.DeleteObject();
-
- BOOL bResult = CreateBannerFont(GetDC(), &m_fontScreen, m_nCurrZoom);
-
- InvalidateRect(NULL);
-
- delete pWait;
-
- if(!bResult)
- {
- if(m_nCurrZoom == 0)
- {
- AfxMessageBox(CString((LPCTSTR)IDS_MESSAGE1));
- ::PostQuitMessage(0);
- }
- else
- {
- AfxMessageBox(CString((LPCTSTR)IDS_MESSAGE2));
- m_nCurrZoom--;
- CMainFrame *pFrame = (CMainFrame *)GetParentFrame();
- if(pFrame != NULL)
- pFrame->m_wndZoomList.SetCurSel(m_nCurrZoom);
- GetDocument()->UpdateAllViews(NULL);
- }
- }
- }
-
-
- /////////////////////////////////////////////////////////////////////////////
- // CBannerView drawing
-
- BOOL CBannerView::OnEraseBkgnd(CDC* pDC)
- {
- CPen pen, *pPrevPen;
- pen.CreateStockObject(NULL_PEN);
- pPrevPen = pDC->SelectObject(&pen);
-
- CBrush brush, *pPrevBrush;
- brush.CreateStockObject(WHITE_BRUSH);
- pPrevBrush = pDC->SelectObject(&brush);
-
- CRect rect;
- GetClientRect(&rect);
- rect.InflateRect(1,1);
- pDC->Rectangle(&rect);
-
- pDC->SelectObject(pPrevPen);
- pen.DeleteObject();
-
- pDC->SelectObject(pPrevBrush);
- brush.DeleteObject();
-
- return TRUE;
- }
-
- void CBannerView::OnDraw(CDC* pDC)
- {
- CSize scroll(-GetDeviceScrollPosition().x, -GetDeviceScrollPosition().y);
- CBannerMetrics mx(pDC, m_nCurrZoom);
-
- pDC->SetBkMode(TRANSPARENT);
-
- if(m_bPageBreaks)
- DrawPageBreaks(pDC, scroll, mx);
-
- if(m_fontScreen.m_hObject != NULL)
- DrawBanner(pDC, scroll, mx);
-
- if(m_bRuler && (mx.ZoomFrac(m_nCurrZoom) >= .24))
- DrawRuler(pDC, scroll, mx);
- }
-
-
- void CBannerView::DrawBanner(CDC *pDC, CSize& scroll, CBannerMetrics& mx)
- {
- CSize& sizeView = pDC->IsPrinting() ? m_sizeViewPrinter : m_sizeViewScreen;
- CSize& sizeText = pDC->IsPrinting() ? m_sizeTextPrinter : m_sizeTextScreen;
- CRect& rcMargins = pDC->IsPrinting() ? m_rcMarginsPrinter : m_rcMarginsScreen;
-
- CRect rcText(0, 0, sizeText.cx, sizeText.cy);
-
- if(GetCenterH())
- rcText.OffsetRect((sizeView.cx-sizeText.cx)/2, 0);
- else
- rcText.OffsetRect(rcMargins.left, 0);
-
- if(GetCenterV())
- rcText.OffsetRect(0, (sizeView.cy-sizeText.cy)/2);
- else
- rcText.OffsetRect(0, rcMargins.top);
-
- if(GetBorder())
- rcText.OffsetRect(mx.BorderGap().cx,mx.BorderGap().cy);
-
- CBrush brush, *pPrevBrush;
- brush.CreateStockObject(NULL_BRUSH);
- pPrevBrush = pDC->SelectObject(&brush);
-
- CFont& font = pDC->IsPrinting() ? m_fontPrinter : m_fontScreen;
- CFont *pPrevFont = pDC->SelectObject(&font);
-
- // Draw the text
- pDC->DrawText(GetBannerText(), &(rcText+scroll), 0);
-
- pDC->SelectObject(pPrevFont);
-
- CPen pen, *pPrevPen;
- pen.CreatePen(PS_SOLID, mx.BorderThickness().cx, 0);
- pPrevPen = pDC->SelectObject(&pen);
-
- // Draw the border
- if(GetBorder())
- {
- rcText.OffsetRect(-mx.BorderGap().cx,-mx.BorderGap().cy);
- pDC->Rectangle(&(rcText+scroll));
- }
-
- pDC->SelectObject(pPrevPen);
- pen.DeleteObject();
-
- pDC->SelectObject(pPrevBrush);
- brush.DeleteObject();
- }
-
- void CBannerView::DrawRuler(CDC *pDC, CSize& scroll, CBannerMetrics& mx)
- {
- int nPrevROP2 = pDC->SetROP2(R2_NOTXORPEN);
-
- CPen pen, *pPrevPen;
- pen.CreateStockObject(BLACK_PEN);
- pPrevPen = pDC->SelectObject(&pen);
-
- CFont font, *pPrevFont;
- font.CreateStockObject(SYSTEM_FONT);
- pPrevFont = pDC->SelectObject(&font);
-
- TCHAR szInchNum[4];
- POINT pt[2];
- for(int nInchNum=1; nInchNum <= m_sizeViewScreen.cx/mx.Inch().cx; nInchNum++)
- {
- pt[0].x = nInchNum*mx.Inch().cx+scroll.cx;
- pt[0].y = 0;
- pt[1].x = pt[0].x;
- pt[1].y = s_nRulerTickSize;
- pDC->Polyline(pt,2);
-
- pt[0].x = pt[1].x-s_nRulerNumberSize;
- pt[0].y = pt[0].y;
- pt[1].x = pt[0].x+s_nRulerNumberSize;
- pt[1].y = pt[0].y+s_nRulerNumberSize;
- pDC->DrawText(_itow(nInchNum,szInchNum,10), -1, (LPRECT)pt, DT_RIGHT | DT_TOP);
- }
-
- for(nInchNum=1; nInchNum <= m_sizeViewScreen.cy/mx.Inch().cy; nInchNum++)
- {
- pt[0].x = 0;
- pt[0].y = nInchNum*mx.Inch().cy+scroll.cy;
- pt[1].x = s_nRulerTickSize;
- pt[1].y = pt[0].y;
- pDC->Polyline(pt,2);
-
- pt[0].x = pt[0].x;
- pt[0].y = pt[1].y-s_nRulerNumberSize;
- pt[1].x = pt[0].x+s_nRulerNumberSize;
- pt[1].y = pt[0].y+s_nRulerNumberSize;
- pDC->DrawText(_itow(nInchNum,szInchNum,10), -1, (LPRECT)pt, DT_LEFT | DT_BOTTOM);
- }
-
- pDC->SelectObject(pPrevFont);
- font.DeleteObject();
-
- pDC->SelectObject(pPrevPen);
- pen.DeleteObject();
-
- pDC->SetROP2(nPrevROP2);
- }
-
- void CBannerView::DrawPageBreaks(CDC *pDC, CSize& scroll, CBannerMetrics& mx)
- {
- int nPageNum;
- POINT pt[2];
-
- CPen pen, *pPrevPen;
- pen.CreatePen(PS_SOLID, 0, 0);
- pPrevPen = pDC->SelectObject(&pen);
-
- CBrush brush, *pPrevBrush;
- brush.CreateStockObject(NULL_BRUSH);
- pPrevBrush = pDC->SelectObject(&brush);
-
- CRect rcArea = CRect(m_rcMarginsScreen.left,
- m_rcMarginsScreen.top,
- m_sizeViewScreen.cx-m_rcMarginsScreen.right,
- m_sizeViewScreen.cy-m_rcMarginsScreen.bottom);
- pDC->Rectangle(&(rcArea+scroll));
-
- for(nPageNum=1; nPageNum < m_sizePageCount.cx; nPageNum++)
- {
- pt[0].x = nPageNum*m_sizePageScreen.cx+scroll.cx;
- pt[0].y = rcArea.top+scroll.cy;
- pt[1].x = pt[0].x;
- pt[1].y = rcArea.bottom+scroll.cy;
- pDC->Polyline(pt,2);
- }
-
- for(nPageNum=1; nPageNum < m_sizePageCount.cy; nPageNum++)
- {
- pt[0].x = rcArea.left+scroll.cx;
- pt[0].y = nPageNum*m_sizePageScreen.cy+scroll.cy;
- pt[1].x = rcArea.right+scroll.cx;
- pt[1].y = pt[0].y;
- pDC->Polyline(pt,2);
- }
-
- pDC->SelectObject(pPrevPen);
- pen.DeleteObject();
-
- pDC->SelectObject(pPrevBrush);
- brush.DeleteObject();
- }
-
-
- /////////////////////////////////////////////////////////////////////////////
- // CBannerView scrolling
-
- // Since we don't want the ruler to be scrolled (it always stays at top and left), we need
- // to implement our own OnScrollBy (same as CScrollView::OnScrollBy except we don't call ScrollWindowEx)
- BOOL CBannerView::OnScrollBy(CSize sizeScroll, BOOL bDoScroll)
- {
- int xOrig, x;
- int yOrig, y;
-
- // don't scroll if there is no valid scroll range (ie. no scroll bar)
- CScrollBar* pBar;
- DWORD dwStyle = GetStyle();
- pBar = GetScrollBarCtrl(SB_VERT);
- if ((pBar != NULL && !pBar->IsWindowEnabled()) ||
- (pBar == NULL && !(dwStyle & WS_VSCROLL)))
- {
- // vertical scroll bar not enabled
- sizeScroll.cy = 0;
- }
- pBar = GetScrollBarCtrl(SB_HORZ);
- if ((pBar != NULL && !pBar->IsWindowEnabled()) ||
- (pBar == NULL && !(dwStyle & WS_HSCROLL)))
- {
- // horizontal scroll bar not enabled
- sizeScroll.cx = 0;
- }
-
- // adjust current x position
- xOrig = x = GetScrollPos(SB_HORZ);
- int xMax = GetScrollLimit(SB_HORZ);
- x += sizeScroll.cx;
- if (x < 0)
- x = 0;
- else if (x > xMax)
- x = xMax;
-
- // adjust current y position
- yOrig = y = GetScrollPos(SB_VERT);
- int yMax = GetScrollLimit(SB_VERT);
- y += sizeScroll.cy;
- if (y < 0)
- y = 0;
- else if (y > yMax)
- y = yMax;
-
- // did anything change?
- if (x == xOrig && y == yOrig)
- return FALSE;
-
- if (bDoScroll)
- {
- InvalidateRect(NULL); // Instead of calling ScrollWindowEx
-
- if (x != xOrig)
- SetScrollPos(SB_HORZ, x);
- if (y != yOrig)
- SetScrollPos(SB_VERT, y);
- }
- return TRUE;
- }
-
-
-
- /////////////////////////////////////////////////////////////////////////////
- // CBannerView command handlers
-
- void CBannerView::OnBannerText()
- {
- m_BannerDlg.DoModal(GetDC());
- GetDocument()->UpdateAllViews(NULL);
- }
-
-
- void CBannerView::OnRuler()
- {
- m_bRuler = !m_bRuler;
- InvalidateRect(NULL);
- }
-
- void CBannerView::OnUpdateRuler(CCmdUI* pCmdUI)
- {
- if(pCmdUI->m_pMenu != NULL)
- pCmdUI->m_pMenu->CheckMenuItem(ID_RULER, m_bRuler ? MF_CHECKED : MF_UNCHECKED);
- }
-
- void CBannerView::OnPageBreaks()
- {
- m_bPageBreaks = !m_bPageBreaks;
- InvalidateRect(NULL);
- }
-
- void CBannerView::OnUpdatePageBreaks(CCmdUI* pCmdUI)
- {
- if(pCmdUI->m_pMenu != NULL)
- pCmdUI->m_pMenu->CheckMenuItem(ID_PAGES, m_bPageBreaks ? MF_CHECKED : MF_UNCHECKED);
- }
-
- int CBannerView::OnCreate(LPCREATESTRUCT lpCreateStruct)
- {
- if (CScrollView::OnCreate(lpCreateStruct) == -1)
- return -1;
-
- // CZoomList::Initialize() calls GetActiveView(), so we need to set the active view.
- GetParentFrame()->SetActiveView(this);
- return 0;
- }
-
-
-
- /////////////////////////////////////////////////////////////////////////////
- // CBannerView printing
-
- // Superfunction of CPrintDialog::DoModal
- BOOL CBannerView::OnPreparePrinting(CPrintInfo* pInfo)
- {
- CPrintDialog *pPD = pInfo->m_pPD;
-
- // Turn off print range selection.
- pPD->m_pd.dwFlags |= PD_DISABLEPRINTRANGE;
-
- // Pass in margins
- pPD->m_pd.dwFlags |= PD_MARGINS | PD_INTHOUSANDTHSOFINCHES;
- memcpy(&pPD->m_pd.rcMargin, &m_rcMarginsPrintDlg, sizeof(RECT));
-
- // Set portrait/landscape
- pPD->m_pd.dwFlags |= (m_sizePagePrinter.cy > m_sizePagePrinter.cx) ?
- PD_SELECTPORTRAIT : PD_SELECTLANDSCAPE;
-
- // Call print dialog box (and whatever else is done in DoPreparePrinting).
- BOOL bResult = DoPreparePrinting(pInfo);
-
- // Get new margins, converting if necessary
- // Note: we could have called CPrintDialog::GetMargins() here.
- memcpy(&m_rcMarginsPrintDlg, &pPD->m_pd.rcMargin, sizeof(RECT));
- if(pPD->m_pd.dwFlags & PD_INHUNDREDTHSOFMILLIMETERS)
- {
- // convert to 1000ths of inches (divide by 2.54)
- m_rcMarginsPrinter.left = (int)(m_rcMarginsPrinter.left * 100 / 254);
- m_rcMarginsPrinter.right = (int)(m_rcMarginsPrinter.right * 100 / 254);
- m_rcMarginsPrinter.top = (int)(m_rcMarginsPrinter.top * 100 / 254);
- m_rcMarginsPrinter.bottom = (int)(m_rcMarginsPrinter.bottom * 100 / 254);
- }
- InvalidateRect(NULL); // repaint window because the printer settings may have changed
-
- return bResult;
- }
-
- // Gets called after the print dialog box but before the first page.
- // We are responsible for setting information in CPrintInfo
- void CBannerView::OnBeginPrinting(CDC* pPrinterDC, CPrintInfo* pInfo)
- {
- ComputeSizes (pPrinterDC);
-
- pInfo->SetMinPage(1);
- pInfo->SetMaxPage(m_sizePageCount.cx * m_sizePageCount.cy);
-
- BOOL bResult = CreateBannerFont(pPrinterDC, &m_fontPrinter);
- if(!bResult)
- {
- AfxMessageBox(CString((LPCTSTR)IDS_MESSAGE3));
- pInfo->m_bContinuePrinting = FALSE;
- }
- }
-
- // Gets called at the beginning of each page (for both screen drawing and printing).
- // If the number of pages had not been set in OnBeginPrinting, we're supposed to
- // set m_bContinuePrinting to FALSE. For this sample, nothing needs to be done here.
- void CBannerView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
- {
- }
-
- // Gets called to print a page
- void CBannerView::OnPrint(CDC* pDC, CPrintInfo* pInfo)
- {
- CSize page((pInfo->m_nCurPage-1) % m_sizePageCount.cx,
- (pInfo->m_nCurPage-1) / m_sizePageCount.cx);
-
- CSize scroll(-page.cx*m_sizePagePrinter.cx, -page.cy*m_sizePagePrinter.cy);
- CBannerMetrics mx(pDC);
-
- if(m_fontPrinter.m_hObject != NULL)
- DrawBanner(pDC, scroll, mx);
- }
-
- // Gets called at the end of a print job.
- void CBannerView::OnEndPrinting(CDC*pDC, CPrintInfo* pInfo)
- {
- if(m_fontPrinter.m_hObject != NULL)
- m_fontPrinter.DeleteObject();
- }
-
- void CBannerView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
- {
- int nMapMode;
- CSize sizeTotal, sizePage, sizeLine;
- GetDeviceScrollSizes(nMapMode, sizeTotal, sizePage, sizeLine);
-
- if(nChar == VK_UP)
- OnScrollBy(CSize(0,-sizeLine.cy));
- else if(nChar == VK_DOWN)
- OnScrollBy(CSize(0,sizeLine.cy));
- else if(nChar == VK_LEFT)
- OnScrollBy(CSize(-sizeLine.cx,0));
- else if(nChar == VK_RIGHT)
- OnScrollBy(CSize(sizeLine.cx,0));
- else
- CScrollView::OnKeyDown(nChar, nRepCnt, nFlags);
- }
-